﻿using Core.Entities;
using Core.IPepositories;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Infrastructure.Repositories
{
    public abstract class EntityRepository<T> : IEntityRepository<T> where T : Entity
    {
        private readonly BMSContext _db;

        public EntityRepository(BMSContext db)
        {
            _db = db;
        }
        public void Delete(Guid ID)
        {
            var t = _db.Set<T>().Find(ID);
            t.IsDeleted = 1;
        }

        public void Delete(T entity)
        {
            _db.Set<T>().Find(entity.ID).IsDeleted = 1;
        }

        public void Delete(Expression<Func<T, bool>> where)
        {
            _db.Set<T>().Where(where).ToList().ForEach(t => t.IsDeleted = 1);
        }

        public T Get(Guid ID)
        {
            return _db.Set<T>().FirstOrDefault(t => t.IsDeleted != 1 && t.ID == ID);
        }

        public List<T> GetList()
        {
            return _db.Set<T>().Where(t => t.IsDeleted != 1).ToList();
        }

        public T Insert(T entity)
        {
            entity.CreateTime = DateTime.Now;
            _db.Set<T>().Add(entity);
            return entity;
        }

        public void Insert(List<T> entities)
        {
            _db.Set<T>().AddRange(entities);
        }
        public T InsertOrUpdate(T entity)
        {
            if (Get(entity.ID) != null) {
                return Update(entity);
            }

            return Insert(entity);
        }

        public IQueryable<T> LoadPageList(int startPage, int pageSize, out int rowCount, Expression<Func<T, bool>> where, Expression<Func<T, object>> order)
        {
            var result = from p in _db.Set<T>().Where(t => t.IsDeleted != 1)
                         select p;
            if (where != null)
                result = result.Where(where);
            if (order != null)
                result = result.OrderBy(order);
            else
                result = result.OrderBy(m => m.ID);
            rowCount = result.Count();
            return result.Skip((startPage - 1) * pageSize).Take(pageSize);
        }

        public T Update(T entity)
        {
            _db.Entry<T>(entity).State = EntityState.Deleted;
            _db.Set<T>().Update(entity);
            return entity;
        }

    }
}
